<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>snake</title>
	<script src="https://cdn.jsdelivr.net/npm/vue"></script>
	<style>
		td{
			border: 1px solid #666;
			width: 10px;
			height: 10px;
		}
		table{
			border-collapse: collapse;
		}
		.active{background: #f60}
	</style>
</head>
<body>
	<div id="snake">
		<table>
		<tr v-for="(col,y) in cols"><td v-for="(row,x) in rows" :class="body(x,y)||showfood(x,y)?'active':''"></td></tr>
		</table>
		<button @click="start()">开始</button>
	</div>
	<script>
		let timer=''//定时器
		new Vue({
			el:'#snake',
			data(){
				return{
					rows:'',//横框
					cols:'',//竖框
					position:[[0,0],[1,0],[2,0],[3,0]],//蛇的初始位置
					direction:1,//方向
					food:[]//食物的位置
				}
			},
			mounted(){
				this.keyboard()
			    this.background() 
			    this.creatfood()
			},
			methods:{
				background(){//生成横框和竖框的函数
					this.rows=Array(30)
					this.cols=Array(30)
				},
				keyboard(){//键盘事件
					let _this = this;
				    document.onkeydown = function(e){
				    	if(e.keyCode===37){
				    		_this.change(-1)
				    	}else if(e.keyCode===38){
				    		_this.change(-2)
				    	}else if(e.keyCode===39){
				    		_this.change(1)
				    	}else{
				    		_this.change(2)
				    	}
				    }
				},
				creatfood(){//创造食物
					this.food[0]=Math.floor(Math.random()*30)
					this.food[1]=Math.floor(Math.random()*30)
				},
				showfood(x,y){//显示食物
					if(this.food[0]===x&&this.food[1]===y){
						return true
					}
				},
				body(x,y){//显示身体
					let X,Y
					for(i=0;i<this.position.length;i++){
						if(this.position[i][0]===x&&this.position[i][1]===y){
							return true
						}
					}
				},	
				start(){//开始按钮
					timer=setInterval(()=>this.autorun(),300)
				},			
				change(dir){//改变方向
					if(Math.abs(dir)===Math.abs(this.direction)){//如果方向相同或者相反，不做任何操作
						return
					}else{
						this.direction=dir//否则改变方向
					}
				},
				autorun(){					
					let direction=this.direction//目前方向
					let headX,headY
						headX=this.position[this.position.length-1][0]//复制蛇头的X坐标
						headY=this.position[this.position.length-1][1]//复制蛇头的Y坐标
					if(direction===1||direction===-1){//如果方向是在左右跑动     						
							direction>0?headX++:headX--//往右跑X坐标+1，往左跑X坐标-1 										
					}else{
							direction>0?headY++:headY--//如果方向是在上下跑动，Y坐标做对应处理
					}//此时蛇头的下一个坐标位置就是[headX,headY]，接下来就可以判断是否结束游戏，如果结束了，蛇头就没必要添加了
					if(headX<0||headX>29||headY<0||headY>29||this.body(headX,headY)){//当蛇头下一个位置出了边界或者这个位置是符合身体函数（即蛇头撞上了身体）
						alert('Game Over')
						clearInterval(timer)
						this.position=[[0,0],[1,0],[2,0],[3,0]]
						this.creatfood()
						this.direction=1
					}else{//如果蛇头下一个位置是符合规则的						
						this.position.push([headX,headY])//将下一个位置添加进数组，头部长一节
						if(headX!==this.food[0]||headY!==this.food[1]){	//如果下一个头部位置不是食物的位置，即吃食物开始						
								this.position.shift()//我们将尾部去掉，一长一短实现了蛇的走动
						}else{//如果下一个头部位置是食物
							this.creatfood()//不去除尾部，再次创建食物（这里有个小bug，随机的食物有几率与身体重合）
						}
					}									
				}							
			}
		})
	</script>
</body>
</html>